En la última década, Kafka se ha convertido en sinónimo de “mensajería moderna” en muchas conferencias. Pero en el día a día de equipos de ingeniería, RabbitMQ sigue siendo la herramienta correcta para muchos casos. Las dos hacen cosas parecidas desde fuera; por dentro resuelven problemas muy distintos.
Diferencias fundamentales
RabbitMQ es un message broker tradicional. Está diseñado alrededor de colas con enrutamiento flexible (exchanges, bindings, routing keys), acknowledgments por mensaje, y el supuesto de que los consumidores procesan y eliminan.
Kafka es un log distribuido. Mensajes persisten en particiones ordenadas con offset, los consumidores navegan por ese log independientemente, y el sistema está optimizado para throughput masivo con retención configurable.
La diferencia se nota en qué problemas modelan bien cada uno:
- Task queue con reintentos finitos → RabbitMQ gana. Rechaza un mensaje y se re-entrega automáticamente; descarta tras N fallos a dead-letter queue.
- Event sourcing con replay → Kafka gana. Mantiene el log 7 días y cualquier consumidor nuevo puede leer desde el principio.
- RPC asíncrono con correlación → RabbitMQ. La cola de respuestas con
reply_toycorrelation_ides un patrón canónico. - Streaming analytics sobre eventos → Kafka. Kafka Streams o Flink sobre Kafka resuelven esto nativamente.
Patrones clásicos de RabbitMQ
Tres patrones que se implementan limpiamente con RabbitMQ:
Work queue (round-robin)
Una cola única, múltiples consumidores. RabbitMQ reparte mensajes de forma equilibrada. Ideal para procesar imágenes, enviar emails, generar reportes — trabajos independientes donde cualquier worker puede atender cualquier mensaje.
Producer → [queue: emails] → Consumer-1
→ Consumer-2
→ Consumer-3
Publish/subscribe con fanout
Un exchange fanout replica cada mensaje a todas las colas enlazadas. Útil para notificar eventos a múltiples servicios independientes.
Producer → [exchange: user-events (fanout)] → queue-audit → Audit service
→ queue-email → Email service
→ queue-mobile → Mobile push service
Topic routing
Un exchange topic filtra por patrones en la routing key. Permite a consumidores subscribirse a subconjuntos específicos.
Producer → [exchange: orders (topic)] → [queue: orders.premium.#] → Premium handler
→ [queue: orders.*.europe] → EU handler
→ [queue: orders.*.us] → US handler
Ninguno de estos patrones es imposible con Kafka, pero RabbitMQ los expresa directamente con su modelo. En Kafka requieren construcciones sobre particiones y consumer groups.
Cuándo Kafka es mejor
Hay casos donde Kafka supera a RabbitMQ:
- Throughput muy alto. Por encima de ~50k mensajes/segundo sostenidos, Kafka escala mejor horizontalmente.
- Retención larga del log. Si necesitas que los eventos persistan días o semanas para re-procesamiento, Kafka está diseñado para eso.
- Orden estricto por clave. Con particionamiento por clave, Kafka garantiza orden total dentro de la partición. RabbitMQ solo dentro de la cola — y complicado con múltiples consumidores.
- Integración con ecosistema de streaming. Kafka Connect, ksqlDB, Kafka Streams, Flink, Spark Streaming — el ecosistema es rico.
Y NATS como tercera vía
NATS a veces es la mejor opción cuando:
- La latencia importa más que la persistencia (trading, IoT de baja latencia).
- Quieres un broker ligero con footprint mínimo.
- JetStream (el modo con persistencia) cubre los casos simples donde RabbitMQ sería overkill.
No es reemplazo de Kafka en streaming pesado, pero para pub/sub y request/reply compite con RabbitMQ en simplicidad operativa.
Errores comunes en producción
De incidentes vistos con RabbitMQ, tres patrones recurrentes:
- Colas sin límite. Sin
max-lengthox-message-ttl, una cola a la que nadie consume puede crecer hasta llenar el disco. Establece límites explícitos. - Sin dead-letter queue. Mensajes que fallan repetidamente entran en bucle infinito o se pierden silenciosamente. Configura DLX + DLQ y monitoriza la DLQ.
- Prefetch desorbitado.
prefetch_count: 1000con consumidores lentos hace que un consumidor acapare toda la cola. Típicamente 1-10 para trabajos largos, 50-200 para trabajos cortos.
Ver nuestra cobertura relacionada sobre microservicios y la arquitectura de comunicación entre ellos — la decisión de broker es central a ese diseño.
Observabilidad
Cualquiera que sea el broker, monitoriza estas métricas:
- Queue depth. Crecimiento sostenido es señal de que los consumidores no siguen el ritmo.
- Consumer utilization. Tiempo ocupado / tiempo total; valores bajos indican bottleneck en I/O o lógica.
- Redelivery rate. Mensajes re-entregados indica fallos parciales o timeouts mal dimensionados.
- Connection churn. Reconexiones frecuentes agotan recursos del broker.
Prometheus exporters para RabbitMQ exponen todas estas métricas. Alertas sobre ellas se diseñan como describimos en cómo escribir alertas que no se ignoren.
Conclusión
RabbitMQ sigue siendo la mejor elección para un amplio rango de casos: task queues, pub/sub con enrutamiento complejo, RPC asíncrono. Kafka gana cuando el problema es inherentemente de streaming o cuando la escala supera el umbral. Elegir por el caso concreto, no por la moda, es lo que diferencia arquitecturas mantenibles de las que se vuelven pesadilla operativa.
Síguenos en jacar.es para más sobre arquitectura distribuida, mensajería y patrones de integración.